
/*
 * =====================================================================================
 *       Filename:  Lock.h
 *
 *    Description:
 *
 *
 *        Version:  1.0
 *        Created:  03/05/19 11:04:08
 *       Revision:  none
 *       Compiler:  gcc
 *
 *         Author:  liushuyong (), shuyong1999@163.com
 *        Company:  shuyong
 *
 * =====================================================================================
 */

#ifndef  __TTS_SERVICE_LOCK_H__
#define  __TTS_SERVICE_LOCK_H__

#include "CommHead.h"

/* bthread does not achive read/write lock */
#define bthread_rwlock_init     pthread_rwlock_init
#define bthread_rwlock_destroy  pthread_rwlock_destroy
#define bthread_rwlock_rdlock   pthread_rwlock_rdlock
#define bthread_rwlock_wrlock   pthread_rwlock_wrlock
#define bthread_rwlock_unlock   pthread_rwlock_unlock

// bthread mutex   互斥锁
class MutexLock {
  public:
    MutexLock();
    ~MutexLock();

    void lock();
    void unlock();

  private:
    MutexLock(const MutexLock&);
    MutexLock& operator =(const MutexLock&);

  private:
    bthread_mutex_t mMutex;
};

// bthread mutex lock
class MutexLockGuard {
  public:
    explicit MutexLockGuard(MutexLock& m): mMutexLock(m) {
        mMutexLock.lock();
    } ~MutexLockGuard() {
        mMutexLock.unlock();
    } private:
    MutexLockGuard();
    MutexLockGuard(const MutexLockGuard&);
    MutexLockGuard& operator =(const MutexLockGuard&);

  private:
    MutexLock& mMutexLock;
};

// bthread r/w lock  读写锁
class RWLock {
    typedef pthread_rwlock_t bthread_rwlock_t;
  public:
    RWLock();
    ~RWLock();

    void setReadLock();
    void setWriteLock();
    void unlock();

  private:
    RWLock(const RWLock&);
    RWLock& operator =(const RWLock&);

  private:
    bthread_rwlock_t mRWLock;
};

typedef enum {
    B_RLOCK = 0,
    B_WLOCK = 1
} RWLockOpt;

// r/w lock guard
class RWLockGuard {
  public:
    RWLockGuard(RWLock& l, RWLockOpt opt): mRWLock(l) {
        if (B_RLOCK == opt) {
            mRWLock.setReadLock();
        } else {
            mRWLock.setWriteLock();
        }
    }

    ~RWLockGuard() {
        mRWLock.unlock();
    }

  private:
    RWLockGuard();
    RWLockGuard(const RWLockGuard&);
    RWLockGuard& operator =(const RWLockGuard&);

  private:
    RWLock& mRWLock;
};
#endif
